www.gusucode.com > VC++ 屏幕截取(窗口截图、选区截图)、屏幕拾色器、放大镜 > VC++ 屏幕截取(窗口截图、选区截图)、屏幕拾色器、放大镜/code/ScreenTool/FullScreenWnd.cpp

    // SreenWnd.cpp : 实现文件
//

#include "stdafx.h"
#include "ScreenTool.h"
#include "FullScreenWnd.h"
#include <atlimage.h>
#include "common.h"
// CSreenWnd



CFullScreenWnd::CFullScreenWnd()
{
	
	m_brush.CreateSolidBrush(RGB(0, 0, 255));
	//获取4种标准光标资源句柄
	hCursor[0] = LoadCursor(NULL, IDC_CROSS);
	hCursor[1] = LoadCursor(NULL, IDC_SIZENS);
	hCursor[2] = LoadCursor(NULL, IDC_SIZEWE);
	hCursor[3] = LoadCursor(NULL, IDC_SIZEALL);
	hCursor[4] = LoadCursor(NULL, IDC_ARROW);
	m_catchMouse = TRUE;
}

CFullScreenWnd::~CFullScreenWnd()
{
}
BEGIN_MESSAGE_MAP(CFullScreenWnd, CWnd)
	ON_WM_ERASEBKGND()
	ON_WM_MOUSEMOVE()
	ON_WM_RBUTTONDOWN()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_TIMER()
	ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()
// CSreenWnd 消息处理程序
BOOL CFullScreenWnd::OnEraseBkgnd(CDC* pDC)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//定义屏幕宽度,高度
	int nWidth, nHeight;
	//获取屏幕宽度和高度
	nWidth = GetSystemMetrics(SM_CXSCREEN);
	nHeight = GetSystemMetrics(SM_CYSCREEN);
	
	pDC->BitBlt(0, 0, nWidth, nHeight, &m_compatibleDC, 0, 0, SRCCOPY);
	return TRUE;
}


void CFullScreenWnd::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (m_bClip)
		SetCursor(hCursor[0]);
	else
	{
		if (m_catchMouse)
		{
		m_mousePos = CalPointPosition(&m_drawRect, point);
		if (m_mousePos == UPPER || m_mousePos == DOWN)
			SetCursor(hCursor[1]);
		else if(m_mousePos == INNER)
			SetCursor(hCursor[3]);
		else if(m_mousePos == LEFT || m_mousePos == RIGHT)
			SetCursor(hCursor[2]);
		else if(m_mousePos == OUTSIDE)
			SetCursor(hCursor[4]);
		}
		
	}
	CWnd::OnMouseMove(nFlags, point);
}

void CFullScreenWnd::OnRButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	this->ShowWindow(SW_HIDE);
	this->GetParent()->ShowWindow(SW_SHOW);
	this->DestroyWindow();
	m_bClip = TRUE;
	
	CWnd::OnRButtonDown(nFlags, point);
}

void CFullScreenWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//设置定时器

	SetTimer(888, 30, NULL);
	m_oriPoint.x = point.x;
	m_oriPoint.y = point.y;
	m_catchMouse = FALSE;
	CWnd::OnLButtonDown(nFlags, point);
}

void CFullScreenWnd::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	KillTimer(888);
	if (m_bClip)
		m_bClip = FALSE;
	m_catchMouse = TRUE;
	ShowTip();
	CWnd::OnLButtonUp(nFlags, point);
}
//功能:显示提示信息
void CFullScreenWnd::ShowTip()
{
	CDC *pDC;
	pDC = GetDC();
	RECT rt;
	CSize size;
	int x, y;
	//定义屏幕宽度,高度
	int nWidth, nHeight;
	//获取屏幕宽度和高度
	nWidth = GetSystemMetrics(SM_CXSCREEN);
	nHeight = GetSystemMetrics(SM_CYSCREEN);
	//设置背景为透明
	pDC->SetBkMode(TRANSPARENT);
	pDC->SetTextColor(RGB(255, 0, 0));
	CString str(_T("温馨提示: 双击左键为保存图片,单击右键为取消"));
	size = pDC->GetTextExtent(str);
	if (m_drawRect.bottom + size.cy > nHeight)
		y = m_drawRect.top - size.cy - 4;
	else
		y = m_drawRect.bottom + 4;
	x = m_drawRect.right - size.cx;
	if (m_drawRect.right - size.cx < 0)
		x = 0;
	if (m_drawRect.right > nWidth)
		x = nWidth - size.cx;
	rt.left = x;
	rt.top = y;
	rt.right = x + size.cx;
	rt.bottom = y + size.cy;
	pDC->FrameRect(&rt, &m_brush);
	pDC->TextOut(x, y, str, str.GetLength());
	ReleaseDC(pDC);
}

int CFullScreenWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码
	m_bClip = TRUE;	
	CRect rect;
	if (m_compatibleDC.m_hDC == NULL)
	{
		CDC *theDC;
		theDC = GetDC();
		m_compatibleDC.CreateCompatibleDC(theDC);
		ReleaseDC(theDC);
	}
	rect.left = 0;
	rect.top = 0;
	rect.right = GetSystemMetrics(SM_CXSCREEN);
	rect.bottom = GetSystemMetrics(SM_CYSCREEN);
	m_hScreenBmp = CopyScreenToBitmap(&rect);
	CBitmap bitmap, *hOldBitmap;
	bitmap.Attach(m_hScreenBmp);
	hOldBitmap = m_compatibleDC.SelectObject(&bitmap);
	hOldBitmap->DeleteObject();
	return 0;
}

void CFullScreenWnd::OnDestroy()
{
	CWnd::OnDestroy();

	// TODO: 在此处添加消息处理程序代码
}
/*
	功能:
		计算鼠标坐标在绘制的矩形区域中的位置
	参数:
		lpRect 指向绘制的矩形区域
		point 鼠标位置坐标
	返回值:
		鼠标在绘制的矩形区域中的位置
*/
MOUSEPOSITION CFullScreenWnd::CalPointPosition(LPRECT lpRect, POINT point)
{
	//定义返回结果
	MOUSEPOSITION retPos;
	//定义矩形区域宽度,高度
	int nWidth, nHeight;
	//定义矩形区域的坐标位置
	int x1, x2, y1, y2;
	//获取矩形区域的两点位置
	x1 = lpRect->left;
	x2 = lpRect->right;
	y1 = lpRect->top;
	y2 = lpRect->bottom;	
	//计算矩形区域宽度, 高度
	nWidth = x2 - x1;
	nHeight = y2 - y1;
	//计算鼠标是否在矩形区域的内部
	if ((point.x > x1 && point.x < x2) &&(point.y > y1 && point.y < y2))
		retPos = INNER;
	//计算鼠标是否在矩形区域的上条边以中心位置开始的四周2个像素范围的位置
	else if ((point.x >= x1 + nWidth/2 - 2 && point.x <= x1 + nWidth/2 + 2)
			&&(point.y >= y1 - 2 && point.y <= y1 + 2))
		retPos = UPPER;
	//计算鼠标是否在矩形区域的下条边以中心位置开始的四周2个像素范围的位置
	else if ((point.x >= x1 + nWidth/2 - 2 && point.x <= x1 + nWidth/2 + 2)
		&&(point.y >= y2 - 2 && point.y <= y2 + 2))
		retPos = DOWN;
	//计算鼠标是否在矩形区域的左条边以中心位置开始的四周2个像素范围的位置
	else if ((point.x >= x1 - 2 && point.x <= x1 + 2)
		&&(point.y >= y1 + nHeight/2 - 2 && point.y <= y1 + nHeight/2 + 2))
		retPos = LEFT;
	//计算鼠标是否在矩形区域的右条边以中心位置开始的四周2个像素范围的位置
	else if ((point.x >= x2 - 2 && point.x <= x2 + 2)
		&&(point.y >= y1 + nHeight/2 - 2 && point.y <= y1 + nHeight/2 + 2))
		retPos = RIGHT;
	else
		retPos = OUTSIDE;
	return retPos;
}
void CFullScreenWnd::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	TrackDraw();
}
//动态绘制
void CFullScreenWnd::TrackDraw()
{
	CClientDC clientDC(this);
	int nWidth, nHeight;
	//获取屏幕宽度和高度
	nWidth = GetSystemMetrics(SM_CXSCREEN);
	nHeight = GetSystemMetrics(SM_CYSCREEN);
	POINT point;
	//得到当前鼠标的位置
	GetCursorPos(&point);
	//判断是否是截图标志
	if (m_bClip)
	{
		//获取矩形区域
		m_drawRect.left = m_oriPoint.x<point.x?m_oriPoint.x:point.x;
		m_drawRect.top  = m_oriPoint.y<point.y?m_oriPoint.y:point.y;
		m_drawRect.right = m_oriPoint.x<point.x?point.x:m_oriPoint.x;
		m_drawRect.bottom  = m_oriPoint.y<point.y?point.y:m_oriPoint.y;
		//清屏
		clientDC.BitBlt(0, 0, nWidth, nHeight, &m_compatibleDC, 0, 0, SRCCOPY);
		//绘制矩形
		DrawRect(&clientDC, &m_drawRect, &m_brush);
	}
	else 
	{
		int moveWidth, width, moveHeight, height;
		int temp;
		if (m_mousePos == OUTSIDE)
			return;
		//计算鼠标移动的距离
		moveWidth = point.x - m_oriPoint.x;
		moveHeight = point.y - m_oriPoint.y;
		//判断鼠标的位置
		switch (m_mousePos)
		{
			//在矩形区域的内部
		case INNER:
			//获取矩形的宽度和高度
			width = m_drawRect.right - m_drawRect.left;
			height = m_drawRect.bottom - m_drawRect.top;
			//重新计算矩形区域的位置
			m_drawRect.left += moveWidth;
			m_drawRect.top += moveHeight;
			m_drawRect.right = m_drawRect.left + width;
			m_drawRect.bottom = m_drawRect.top + height;	
			break;
			//在矩形区域的上部
		case UPPER:
			if (m_drawRect.top > m_drawRect.bottom)
			{
				
				temp = m_drawRect.top;
				m_drawRect.top = m_drawRect.bottom;
				m_drawRect.bottom = temp;
				m_mousePos = DOWN;
			}
			else
				m_drawRect.top += moveHeight;
			break;
			//在矩形区域的下部
		case DOWN:
			if (m_drawRect.bottom < m_drawRect.top)
			{

				temp = m_drawRect.top;
				m_drawRect.top = m_drawRect.bottom;
				m_drawRect.bottom = temp;
				m_mousePos = UPPER;
			}
			else
				m_drawRect.bottom += moveHeight;
			break;
			//在矩形区域的左部
		case LEFT:
			if (m_drawRect.left > m_drawRect.right)
			{

				temp = m_drawRect.left;
				m_drawRect.left = m_drawRect.right;
				m_drawRect.right = temp;
				m_mousePos = RIGHT;
			}
			else
				m_drawRect.left += moveWidth;
			break;
			//在矩形区域的右部
		case RIGHT:
			if (m_drawRect.right < m_drawRect.left)
			{

				temp = m_drawRect.left;
				m_drawRect.left = m_drawRect.right;
				m_drawRect.right = temp;
				m_mousePos = LEFT;
			}
			m_drawRect.right += moveWidth;
			break;
		default:
			break;
		}	
		//清屏
		clientDC.BitBlt(0, 0, nWidth, nHeight, &m_compatibleDC, 0, 0, SRCCOPY);
		//绘制矩形
		DrawRect(&clientDC, &m_drawRect, &m_brush);
		//重新设置原点
		m_oriPoint = point;	
	}
	ReleaseDC(&clientDC);
}

/*
	功能:
		在指定的设备描述表当中画矩形,以及在矩形四条边上的中心画小矩形框
	参数:
		pDC 指向设备描述表的句柄
		pRect 指向绘制师的矩形的区域
		pBrush 指向绘制时使用的画刷
	返回值:
		void 
*/
void CFullScreenWnd::DrawRect(CDC *pDC, RECT *pRect, CBrush *pBrush)
{
	//定义矩形的宽度,高度
	int width, height;
	//定义画矩形框需要的临时变量
	RECT rt;
	CBrush *oldBrush;
	CPen pen, *oldPen;
	//计算矩形的宽度和高度
	width = pRect->right - pRect->left;
	height = pRect->bottom - pRect->top;
	//画矩形框
	pDC->FrameRect(pRect, pBrush);
	
	//创建画笔
	pen.CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
	oldPen = pDC->SelectObject(&pen);
	oldBrush = pDC->SelectObject(pBrush);

	//在矩形的四条边的中心位置绘制4像素的矩形框
	//在矩形框的上条边的中心位置绘制矩形
	rt.left = pRect->left + width/2 - 2;
	rt.right = pRect->left + width/2 + 2;
	rt.top = pRect->top - 2;
	rt.bottom = pRect->top + 2;
	pDC->Rectangle(&rt);

	//在矩形框的下条边的中心位置绘制矩形
	rt.left = pRect->left + width/2 - 2;
	rt.right = pRect->left + width/2 + 2;
	rt.top = pRect->bottom - 2;
	rt.bottom = pRect->bottom + 2;
	pDC->Rectangle(&rt);

	//在矩形框的左条边的中心位置绘制矩形
	rt.left = pRect->left - 2;
	rt.right = pRect->left + 2;
	rt.top = pRect->top + height/2 - 2;
	rt.bottom = pRect->top + height/2 + 2;
	pDC->Rectangle(&rt);

	//在矩形框的右条边的中心位置绘制矩形
	rt.left = pRect->right - 2;
	rt.right = pRect->right + 2;
	rt.top = pRect->top + height/2 - 2;
	rt.bottom = pRect->top + height/2 + 2;
	pDC->Rectangle(&rt);

	pDC->SelectObject(oldPen);
	pDC->SelectObject(oldBrush);
	pen.DeleteObject();	
}
//保存屏幕矩形区域到一个文件
void CFullScreenWnd::Save()
{
	//定义CImage对象,用来将位图保存到一个文件上
	CImage image;
	//打开文件对话框
	CFileDialog fd(FALSE, _T("png"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, 0, NULL);
	fd.m_ofn.lpstrFilter = _T("PNG 文件\0*.png\0JPEG 文件\0*.jpg\0位图文件\0*.bmp\0All Files\0*.*\0\0");
	fd.DoModal();
	//获取文件路径
	CString strPathName = fd.GetPathName();
	if(strPathName.IsEmpty())
		goto RET;
	//得到矩形区域位图句柄
	HBITMAP hBitmap = CopyDCToBitmap(&m_drawRect, m_compatibleDC.m_hDC);
	//将位图句柄与CImgae对象关联
	image.Attach(hBitmap);
	//保存到文件
	image.Save(strPathName);
	image.Destroy();
RET:
	//向窗口发送鼠标右键按下消息
	SendMessage(WM_RBUTTONDOWN, 0, 0);
}
void CFullScreenWnd::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//保存位图
	Save();
}